﻿#include "FITKAbaqusAdaptorSet.h"
#include "InpKeyLineSpliter.h"
#include "FITKAbaqusINPReader.h"
#include "FITKAbaqusINPWriter.h"
#include "InpReadInformationMapper.h"
#include "InpWriteInformationMapper.h"
#include "FITKAbaqusGetInterfaceTool.h"
#include "FITK_Kernel/FITKCore/FITKVec3D.h"
//#include "FITK_Interface/FITKInterfaceModel/FITKAssInstanceTR.h"
#include "FITK_Interface/FITKInterfaceModel/FITKComponentManager.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaAssembly.h"
#include "FITK_Component/FITKAbaqusData/FITKDataCase.h"
#include "FITK_Component/FITKAbaqusData/FITKAbaqusPart.h"
#include "FITK_Interface/FITKInterfaceStructural/FITKAbaConnectorAssignmentManager.h"
#include <QTextStream>
#include <QList>
#include <QDebug>

//set集合每行不得超过16个，INP准则
#define SETCOUNT 16

namespace IO
{

    QString FITKAbaqusAdaptorSet::getAdaptorClass()
    {
        return "IO::FITKAbaqusAdaptorSet";
    }
    void FITKAbaqusAdaptorSet::setCaseData(AbaqusData::FITKDataCase* caseData)
    {
        _caseData = caseData;
    }

    bool FITKAbaqusAdaptorSet::adaptR()
    {
        //_setData = Interface::FITKModelSet::SafeDownCastFITKModelSet(_dataObj);
        _setData = dynamic_cast<Interface::FITKModelSet*>(_dataObj);

        if (!_setData || !_caseData || !_reader) return false;

        //回退一行 处理关键字信息
        _reader->backLine();

        QString line = _reader->readLine();
        QString setName;
        //处理关键字 获取基础信息
        InpKeyLineSpliter spl(line, _reader);
        QString sH = spl.getHeader().toLower();
        if (sH == "nset")
        {
            _setData->setModelSetType(Interface::FITKModelEnum::FITKModelSetType::FMSNode);
            setName = spl["nset"];   //名字
        }
        else if (sH == "elset")
        {
            _setData->setModelSetType(Interface::FITKModelEnum::FITKModelSetType::FMSElem);
            setName = spl["elset"];   //名字
        }
        else
        {
            return false;
        }
        bool isInternal = spl.hasKey("internal");
        bool isGenerate = spl.hasKey("generate");

        //判断ASSEMBLY下的集合装配名字
        _instanceName = spl["instance"];

        _setData->setDataObjectName(setName);
        _setData->setInternal(isInternal);
        _setData->setGenerated(isGenerate);

        if (setName.startsWith("_T-"))
        {
            _isTrans = true;
            setName.remove("_T-");
        }
        
        FITKAbaqusGetInterfaceTool tool;
        tool.setCaseData(_caseData);
        InpReadInformationMapper* mapper = _reader->getReadInpInformationMapper();
        if (!mapper)return false;
        bool numFlog = false;
        //读取set集合
        while (!_reader->atEnd())
        {
            line = _reader->readLine();
            //关键字段结束
            if (line.startsWith("*"))
            {
                if (_isTrans && numFlog)
                {
                    _isTrans = false;
                    mapper->insertSetDataTransformName(_setData, setName);
                }
                return true;
            }
            QStringList sList = line.split(",");
            for (int i = 0; i < sList.size(); ++i)
            {
                QString str = sList.at(i);
                if (str.trimmed().isEmpty()) continue;
                bool ok = false;
                int member = str.trimmed().toInt(&ok);
                //为了确保一致性（数字或名称）
                if (i == 0)numFlog = ok;
                else
                    if (numFlog != ok)return false;
                if (_isTrans && !ok)
                {
                    int instanceId = 0;
                    Interface::FITKModelSet* set = tool.getSetIDByNamePrivate(str.trimmed(), instanceId);
                    mapper->insertSetDataTransformName(set, setName);
                }
                _setData->appendMember(member);
            }
        }
        //未正常结束 调用者销毁
        return false;
    }

    bool FITKAbaqusAdaptorSet::adaptW()
    {
 //       _setData = Interface::FITKModelSet::SafeDownCastFITKModelSet(_dataObj);
        _setData = dynamic_cast<Interface::FITKModelSet*>(_dataObj);

        if (_setData == nullptr || _writer == nullptr) return false;
        bool isW = true;
        if (_setData->isCombination())
        {
            for (int i = 0; i < _setData->getDataCount(); ++i)
            {
                isW &= writeSet(_setData->getDataByIndex(i));
            }
        }
        else
        {
            isW &= writeSet(_setData);
        }

        return isW;
    }

    bool FITKAbaqusAdaptorSet::writeSet(Interface::FITKModelSet* set)
    {
        if (set == nullptr) return false;
        // 写出节点函数主体
        QTextStream* stream = _writer->getStream();

        //固定的关键字标记
        QString setTitle;
        if (set->getModelSetType() == Interface::FITKModelEnum::FITKModelSetType::FMSNode)
        {
            setTitle = "*Nset, nset=%1";
        }
        else if (set->getModelSetType() == Interface::FITKModelEnum::FITKModelSetType::FMSElem)
        {
            setTitle = "*Elset, elset=%1";
        }
        QString setName = set->getDataObjectName();
        setName = setName.contains(' ') ? QString("\"%1\"").arg(setName) : setName;
        setTitle = setTitle.arg(setName);
        //添加额外的关键字标记
        if (set->isInternal())
        {
            setTitle += ", internal";
        }
        if (set->getAbstractModel() != nullptr && set->getAbstractModel()->getAbsModelType() == Interface::FITKModelEnum::AbsModelType::AssInstance)
        {
            QString instanceName = set->getAbstractModel()->getDataObjectName();
            instanceName = instanceName.contains(' ') ? QString("\"%1\"").arg(instanceName) : instanceName;
            setTitle += ", instance=" + instanceName;
        }
        if (set->isGenerated())
        {
            setTitle += ", generate";
        }

        *stream << setTitle << endl;

        if (this->writeConnectSet(set))return true;

        auto mList = set->getMember();
        int mListCount = mList.count();
        //错误 set下没有任何数据
        if (mListCount < 1) return false;

        //超过一行SETCOUNT个则每行SETCOUNT(16)个，否则 maberCount 作为当前行最大长度
        int lineCount = mListCount > SETCOUNT ? SETCOUNT : mListCount;

        for (int i = 0; i < mListCount; i += lineCount)
        {
            //写出每行的第一个数据
            *stream << _writer->int2String(mList[i], 8) << ",";
            //计算当前行的长度
            lineCount = mListCount - i > SETCOUNT ? SETCOUNT : mListCount - i;

            for (int j = 1; j < lineCount; ++j)
            {
                if (j != 1)
                    *stream << ",";
                *stream << _writer->int2String(mList[i + j], 8);
            }
            *stream << endl;
        }
        return true;
    }


    QString FITKAbaqusAdaptorSet::getInstanceName()
    {
        return _instanceName;
    }

    bool FITKAbaqusAdaptorSet::isTransform()
    {
        return _isTrans;
    }

    bool FITKAbaqusAdaptorSet::writeConnectSet(Interface::FITKModelSet* set)
    {
        if (!set || !_caseData || !_writer) return false;
        int setId = set->getDataObjectID();
        bool isConnectSet = false;
        // 写出节点函数主体
        QTextStream* stream = _writer->getStream();
        //获取映射
        InpWriteInformationMapper* mapper = _writer->getWriteInpInformationMapper();
        if (!mapper)return false;
        //获取装配数据
        Interface::FITKAbaAssembly* assemblyData = _caseData->getAssembly();
        if (!assemblyData)return false;
        //获取连接器指派管理器
        Interface::FITKAbaConnectorAssignmentManager* assignConnectManager = assemblyData->getConnectorAssignManager();
        if (!assignConnectManager)return false;
        //对比set，确定set是否是连接器指派的集合
        int count = assignConnectManager->getDataCount();
        for (int i = 0; i < count; ++i)
        {
            //获取指派
            Interface::FITKAbaConnectorAssignment* connectAssignData = assignConnectManager->getDataByIndex(i);
            if (!connectAssignData)continue;
            //获取集合数据
            Interface::FITKModelSet* setData = connectAssignData->getTModelObj<Interface::FITKModelSet>();
            if (!setData)continue;
            if (setData->getDataObjectID() == setId || setData->getDataByID(setId))
            {
                isConnectSet = true;
                break;
            }
        }
        if (!isConnectSet)return false;
        //获取成员
        auto mList = set->getMember();
        int mListCount = mList.count();
        //错误 set下没有任何数据
        if (mListCount < 1) return false;

        //超过一行SETCOUNT个则每行SETCOUNT(16)个，否则 maberCount 作为当前行最大长度
        int lineCount = mListCount > SETCOUNT ? SETCOUNT : mListCount;

        for (int i = 0; i < mListCount; i += lineCount)
        {
            //写出每行的第一个数据
            *stream << _writer->int2String(mapper->getWriteConnectElemID(mList[i]), 8) << ",";
            //计算当前行的长度
            lineCount = mListCount - i > SETCOUNT ? SETCOUNT : mListCount - i;

            for (int j = 1; j < lineCount; ++j)
            {
                if (j != 1)
                    *stream << ",";
                *stream << _writer->int2String(mapper->getWriteConnectElemID(mList[i + j]), 8);
            }
            *stream << endl;
        }
        return true;
    }
}
